using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace Sandia.MVCFramework.Common
{
    /// <summary>
    /// A delegate used for events relating to a control being pinned.
    /// </summary>
    /// <param name="wrapper">The ControlWrapper that is being pinned.</param>
    /// <param name="control">The control that is being pinned.</param>
    public delegate void OnControlPinnedChanged(Control wrapper, Control control);

    /// <summary>
    /// A wrapper class used to wrap around Controls and provide a pinning 
    /// interface.
    /// </summary>
    public partial class PinnableControlWrapper : UserControl
    {
        /// <summary>
        /// The control to wrap.
        /// </summary>
        private Control control;

        /// <summary>
        /// The image to use when the control is not pinned.
        /// </summary>
        private Image pushPinNormal;

        /// <summary>
        /// The image to use when the control is pinned.
        /// </summary>
        private Image pushPinPushed;

        /// <summary>
        /// Indicates whether the control is pinned or not.
        /// </summary>
        private bool pinned = false;

        /// <summary>
        /// Event fired when the control is pinned.
        /// </summary>
        public event OnControlPinnedChanged ControlPinned;

        /// <summary>
        /// Event fired when the control is unpinned.
        /// </summary>
        public event OnControlPinnedChanged ControlUnpinned;

        /// <summary>
        /// Constructor for PinnableControlWrapper.
        /// </summary>
        /// <param name="controlName">A displayable name for the control.</param>
        /// <param name="control">The control to wrap.</param>
        public PinnableControlWrapper(
            string controlName,
            Control control)
        {
            InitializeComponent();
            this.controlNameLabel.Name = "controlNameLabel";
            this.control = control;
            this.Width = this.control.Width;
            this.controlNameLabel.Text = controlName;
            this.control.Dock = DockStyle.Fill;
            this.panel1.Controls.Add(this.control);

            Assembly thisExe = Assembly.GetExecutingAssembly();
            Stream file =
                    thisExe.GetManifestResourceStream(
                        "Sandia.MVCFramework.Common.PushpinNormal.bmp");
            Bitmap image = (Bitmap)Bitmap.FromStream(file);
            image.MakeTransparent();
            this.pushPinNormal = image;

            file =
                    thisExe.GetManifestResourceStream(
                        "Sandia.MVCFramework.Common.PushpinPushed.bmp");
            image = (Bitmap)Bitmap.FromStream(file);
            image.MakeTransparent();
            this.pushPinPushed = image;
            this.pushpinBtn.Image = this.pushPinNormal;
        }

        /// <summary>
        /// Called when focus enters the control. Changes the color of the 
        /// control.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event arguments.</param>
        private void ControlWrapper_Enter(
            object sender, 
            EventArgs e)
        {
            this.toolStrip1.BackColor = SystemColors.ActiveCaption;
            this.toolStrip1.ForeColor = SystemColors.ActiveCaptionText;
        }

        /// <summary>
        /// Called when focus leaves the control. Changes the color of the 
        /// control.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The event arguments.</param>
        private void ControlWrapper_Leave(
            object sender, 
            EventArgs e)
        {
            this.toolStrip1.BackColor = SystemColors.InactiveBorder;
            this.toolStrip1.ForeColor = SystemColors.InactiveCaptionText;
        }

        /// <summary>
        /// Called when the pushpin button is clicked. Toggles the image and
        /// fires the appropriate event.
        /// </summary>
        /// <param name="sender">The button.</param>
        /// <param name="e">The event arguments.</param>
        private void pushpinBtn_Click(
            object sender, 
            EventArgs e)
        {
            if (this.pinned)
            {
                this.pushpinBtn.Image = this.pushPinNormal;
                this.pinned = false;
                if (this.ControlUnpinned != null)
                {
                    this.ControlUnpinned(this, this.control);
                }
            }
            else
            {
                this.pushpinBtn.Image = this.pushPinPushed;
                this.pinned = true;
                if (this.ControlPinned != null)
                {
                    this.ControlPinned(this, this.control);
                }
            }
        }
    }
}
